﻿using MES.Desktop.Common;
using MES.Desktop.Controls;
using MES.Desktop.Entities;
using MES.Desktop.IService;
using MES.Desktop.SystemModule.Models;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace MES.Desktop.SystemModule.ViewModels
{
    public class UserViewModel : PageViewModelBase
    {
        public ObservableCollection<UserModel> Users { get; set; } =
            new ObservableCollection<UserModel>();

        public ObservableCollection<DepartModel> Departs { get; set; } =
            new ObservableCollection<DepartModel>()
            {
                new DepartModel{ DepartName="全部",DepartId=0,IsSelected=true}
            };

        public ObservableCollection<PostModel> Posts { get; set; } =
            new ObservableCollection<PostModel>
            {
                new PostModel{ PostName="全部",PostId=0,IsSelected=true}
            };

        public PaginationModel PaginationModel { get; set; } =
          new PaginationModel();

        public DelegateCommand<object> ResetPasswordCommand { get; set; }
        public DelegateCommand<object> LockUserCommand { get; set; }

        public DelegateCommand<object> SelectRoleCommand { get; set; }

        private bool isSyncSelect;
        private bool _isSelectAll;

        public bool IsSelectAll
        {
            get { return _isSelectAll; }
            set
            {
                SetProperty<bool>(ref _isSelectAll, value);

                if (isSyncSelect) return;
                isSyncSelect = true;

                foreach (var user in Users)
                    user.IsSelected = value;

                isSyncSelect = false;
            }
        }

        bool _isLoadCondition = false;

        IEventAggregator _eventAggregator;
        IUserService _userService;
        GlobalValues _globalValues;
        IDepartService _departService;
        IPostService _postService;
        IDialogService _dialogService;
        IRoleService _roleService;
        public UserViewModel(IRegionManager regionManager,
            IEventAggregator eventAggregator,
            IUserService userService,
            IDepartService departService,
            IPostService postService,
            GlobalValues globalValues,
            IDialogService dialogService,
            IRoleService roleService)
            : base(regionManager)
        {
            this.PageTitle = "系统用户管理";

            _eventAggregator = eventAggregator;
            _userService = userService;
            _globalValues = globalValues;
            _departService = departService;
            _postService = postService;
            _dialogService = dialogService;
            _roleService = roleService;
            _isLoadCondition = true;
            this.Refresh();

            PaginationModel.NavCommand = new DelegateCommand<object>(index =>
            {
                PaginationModel.PageIndex = int.Parse(index.ToString());
                this.Refresh();
            });

            ResetPasswordCommand = new DelegateCommand<object>(DoResetPassword);
            LockUserCommand = new DelegateCommand<object>(DoLockUser);
            SelectRoleCommand = new DelegateCommand<object>(DoSelectRole);
        }

        public override void Refresh()
        {
            Users.Clear();

            _eventAggregator.GetEvent<LoadingEvent>()
                .Publish("正在加载用户....");

            Task.Run(() =>
            {
                try
                {
                    string[] ds = Departs
                            .Where(d => d.IsSelected)
                            .Select(d => d.DepartId.ToString()).ToArray();
                    string[] ps = Posts
                            .Where(p => p.IsSelected)
                            .Select(p => p.PostId.ToString()).ToArray();

                    // 请求用户
                    var page = _userService.GetUsers(SearchKey, ds, ps, PaginationModel.PageIndex, PaginationModel.PageSize);
                    int index = 0;
                    foreach (var user in page.Data)
                    {
                        index++;

                        UserModel model = new UserModel
                        {
                            Index = index + (PaginationModel.PageIndex - 1) * PaginationModel.PageSize,
                            UserId = user.userId,
                            UserName = user.userName,
                            RealName = user.realName,
                            UserIcon = $"{_globalValues.ServerHost}/api/File/img/" + user.eIcon,
                            Address = user.address,
                            Age = user.age,
                            Phone = user.phone,
                            Password = user.password,
                            Gender = user.gender,
                            Email = user.email,
                            Status = user.status,

                            DepartId = user.departId,
                            DepartName = user.departName,
                            PostId = user.postId,
                            PostName = user.postName,
                        };

                        // 需要根据当前用户的角色ID进行角色数据的获取
                        int[] role_ids = user.roles.Select(r => r.roleId).ToArray();
                        var roles = _roleService.GetRoleByIds(role_ids);

                        model.Roles = roles.Select(r => new RoleModel
                        {
                            RoleId = r.RoleId,
                            RoleName = r.RoleName,
                        }).ToList();

                        model.PropertyChanged += (se, ev) =>
                        {
                            if (isSyncSelect) return;
                            isSyncSelect = true;

                            if (ev.PropertyName == "IsSelected")
                                this.IsSelectAll = Users.All(f => f.IsSelected);

                            isSyncSelect = false;
                        };



                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            Users.Add(model);
                            // 刷新分页组件的页码
                            PaginationModel.FillPageNumbers(page.TotalCount);

                        });
                    }

                    if (_isLoadCondition)
                    {
                        _isLoadCondition = false;

                        // 请求部门
                        var departs = _departService.GetAllDeparts().ToList();
                        for (int i = 0; i < departs.Count; i++)
                        {
                            var depart = departs[i];

                            DepartModel model = new DepartModel();
                            model.Index = i + 1;
                            model.DepartId = departs[i].DepartId;
                            model.DepartName = departs[i].DepartName;

                            model.PropertyChanged += DepartModel_PropertyChanged;

                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                Departs.Add(model);
                            });
                        }

                        // 请求职位
                        var posts = _postService.GetAllPosts().ToList();
                        for (int i = 0; i < posts.Count; i++)
                        {
                            var depart = posts[i];

                            PostModel model = new PostModel();
                            model.Index = i + 1;
                            model.PostId = posts[i].PostId;
                            model.PostName = posts[i].PostName;

                            model.PropertyChanged += PostModel_PropertyChanged;

                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                Posts.Add(model);
                            });
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "提示");
                }
                finally
                {
                    _eventAggregator.GetEvent<LoadingEvent>()
                        .Publish("");
                }
            });
        }

        private void PostModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsSelected")
            {
                var model = sender as PostModel;
                if (model.IsSelected)
                {
                    if (model.PostId == 0)
                        for (int i = 1; i < Posts.Count; i++)
                        {
                            Posts[i].PropertyChanged -= PostModel_PropertyChanged;
                            Posts[i].IsSelected = false;
                            Posts[i].PropertyChanged += PostModel_PropertyChanged;
                        }
                    else
                    {
                        Posts[0].PropertyChanged -= PostModel_PropertyChanged;
                        Posts[0].IsSelected = false;
                        Posts[0].PropertyChanged += PostModel_PropertyChanged;
                    }
                }
                else
                {
                    Posts[0].PropertyChanged -= PostModel_PropertyChanged;
                    Posts[0].IsSelected =
                        !(Posts.ToList().Exists(p => p.IsSelected));
                    Posts[0].PropertyChanged += PostModel_PropertyChanged;
                }

            }
        }

        private void DepartModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsSelected")
            {
                var model = sender as DepartModel;
                if (model.IsSelected)
                {
                    if (model.DepartId == 0)
                        for (int i = 1; i < Departs.Count; i++)
                        {
                            Departs[i].PropertyChanged -= DepartModel_PropertyChanged;
                            Departs[i].IsSelected = false;
                            Departs[i].PropertyChanged += DepartModel_PropertyChanged;
                        }
                    else
                    {
                        Departs[0].PropertyChanged -= DepartModel_PropertyChanged;
                        Departs[0].IsSelected = false;
                        Departs[0].PropertyChanged += DepartModel_PropertyChanged;
                    }
                }
                else
                {
                    Departs[0].PropertyChanged -= DepartModel_PropertyChanged;
                    Departs[0].IsSelected =
                        !(Departs.ToList().Exists(d => d.IsSelected));
                    Departs[0].PropertyChanged += DepartModel_PropertyChanged;
                }

            }
        }

        public override void DoModify(object model)
        {
            DialogParameters ps = new DialogParameters();
            ps.Add("model", model);
            _dialogService.ShowDialog("ModifyUserView", ps, result =>
            {
                // 判断子窗口的返回状态，如果OK，刷新当前页面，否则不管
                if (result.Result == ButtonResult.OK)
                {
                    this.Refresh();
                }
            });
        }


        public override void DoBatchDelete()
        {
            var ids = Users.Where(u => u.IsSelected)
                           .Select(u => u.UserId).ToArray();
            this.Delete(ids);
        }
        public override void DoDelete(object obj)
        {
            this.Delete(new int[] { (obj as UserModel).UserId });
        }

        private void Delete(int[] ids)
        {
            try
            {
                if (MessageBox.Show("是否确定删除记录？", "提示", MessageBoxButton.YesNo) ==
                    MessageBoxResult.Yes)
                {
                    // 物理删除
                    _userService.DeleteUser(ids);
                    MessageBox.Show("删除完成！", "提示");

                    this.Refresh();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示");
            }

        }

        // 重置密码
        private void DoResetPassword(object model)
        {
            try
            {
                if (MessageBox.Show("是否确定重置当前用户密码？", "提示", MessageBoxButton.YesNo) ==
                    MessageBoxResult.Yes)
                {
                    var m = model as UserModel;
                    _userService.ResetPassword(m.UserId);

                    MessageBox.Show("重置完成！", "提示");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示");
            }
        }
        private void DoLockUser(object model)
        {
            try
            {
                var ui = model as UserModel;
                int status = 0;
                if (ui.Status == 1)
                {
                    if (MessageBox.Show("是否锁定前用户？", "提示", MessageBoxButton.YesNo) ==
                        MessageBoxResult.Yes)
                    {
                        _userService.LockUser(ui.UserId, 0);
                    }
                }
                else
                {
                    status = 1;
                    _userService.LockUser(ui.UserId, 1);
                }

                MessageBox.Show("操作已完成！", "提示");

                ui.Status = status;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示");
            }
        }
        private void DoSelectRole(object model)
        {
            DialogParameters ps = new DialogParameters();
            ps.Add("model", model);
            _dialogService.ShowDialog("SelectRoleView", ps, result =>
            {
                // 判断子窗口的返回状态，如果OK，刷新当前页面，否则不管
                if (result.Result == ButtonResult.OK)
                {
                    this.Refresh();
                }
            });
        }
    }
}
